Skip to content

Add independent tagged README actions, panel view, and editor round-trip integration for both conventional paths - #459

Merged
eXamadeus merged 2 commits into
mainfrom
julian/07-23-add_independent_tagged_readme_actions_panel_view_and_editor_round-trip_integration_for_both_conventional_paths
Jul 24, 2026
Merged

Add independent tagged README actions, panel view, and editor round-trip integration for both conventional paths#459
eXamadeus merged 2 commits into
mainfrom
julian/07-23-add_independent_tagged_readme_actions_panel_view_and_editor_round-trip_integration_for_both_conventional_paths

Conversation

@eXamadeus

@eXamadeus eXamadeus commented Jul 24, 2026

Copy link
Copy Markdown
Member

Why

Task 13.4: each of the two conventional README paths (README.md and README) now has its own independent tagged action state, managed separately rather than merged into a single choice. This ensures scaffold, edit, removal, and declaration changes are always applied to the exact path the author acted on, and that adopting an existing file preserves its bytes structurally (no file write is ever queued for adopt).

Details

A new ReadmeAction discriminated union in readme-actions.ts is the single source of truth for what can happen to a README path. Each variant is only constructible for states that permit it — readmeActionOptions returns the legal options per state, and readmeActionFor maps a chosen option kind back to the tagged action, so an illegal state/action pairing cannot be represented.

The two paths are tracked independently in useEditSession via a readmeActions: Map<ReadmePath, ReadmeAction> alongside the existing resolutions map. buildResult filters out none actions, applies declaration deltas via applyReadmeDeclaration, and emits file operations via readmeFileOperations — these two concerns are kept separate so adoption never queues a write.

A new readme phase is inserted into the edit wizard between reconciliation and editing, rendered by ReadmePanelView. Each row shows the path's current on-disk/declaration state and its legal options; left/right arrows move the highlight and Enter selects. Content-bearing options (edit, edit-and-adopt, create) route to the external editor via the existing round-trip mechanism. The EditEditorRequest type is now a tagged union (asset-description | readme) so the command runner's applyEditorRoundTrip function handles each arm correctly — a cancelled editor for a README path queues nothing rather than writing empty content.

readmeSeedContent provides the editor seed: existing bytes for present files, or the facet identity template for absent ones, sharing the same template used by create.

Verification

New unit tests in edit-supplementary.test.ts cover readmeActionOptions for all four states, and each action variant's declaration delta and file operations — including the structural byte-preservation guarantee for adopt and the round-trip of readmeOptionKindFor.


Note

Medium Risk
Changes manifest files and on-disk supplementary paths during edit/create flows, but behavior is constrained by tagged actions, transactional apply, and broad new test coverage.

Overview
Adds engine-level README authoring via a ReadmeAction discriminated union in readme-actions.ts, with state-specific options, separate manifest declaration updates (applyReadmeDeclaration) and exact-path file ops (readmeFileOperations). Adopt only updates files and never queues a write, so on-disk bytes stay intact.

The edit TUI gains a dedicated readme phase (ReadmePanelView) between reconciliation and asset editing. README.md and extensionless README are tracked independently in useEditSession (readmeActions map). Content choices use a tagged EditEditorRequest (asset-description | readme); cancelling the external editor leaves README paths unchanged.

Confirmation shows queued README writes/deletes by exact path (via existing previewEditOperations). E2E create tests cover scaffold/build with an enabled README and headless default --no-readme behavior. OpenSpec tasks 13.4, 13.7, and 13.8 are marked complete.

Reviewed by Cursor Bugbot for commit 9ba621d. Bugbot is set up for automated code reviews on this repo. Configure here.

@changeset-bot

changeset-bot Bot commented Jul 24, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 9ba621d

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@eXamadeus, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 53 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 11454063-9bb1-4498-9b0b-dda7e224b929

📥 Commits

Reviewing files that changed from the base of the PR and between 4bd6831 and 9ba621d.

📒 Files selected for processing (11)
  • openspec/changes/support-non-asset-files/tasks.md
  • packages/cli/src/__tests__/create-build.e2e.test.ts
  • packages/cli/src/commands/edit/wizard.tsx
  • packages/cli/src/tui/views/__tests__/confirm-privacy.test.tsx
  • packages/cli/src/tui/views/edit/__tests__/readme-session.test.tsx
  • packages/cli/src/tui/views/edit/readme-panel-view.tsx
  • packages/cli/src/tui/views/edit/use-edit-session.ts
  • packages/cli/src/tui/views/edit/wizard.tsx
  • packages/engine/src/__tests__/edit-supplementary.test.ts
  • packages/engine/src/edit/readme-actions.ts
  • packages/engine/src/index.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch julian/07-23-add_independent_tagged_readme_actions_panel_view_and_editor_round-trip_integration_for_both_conventional_paths

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

eXamadeus commented Jul 24, 2026

Copy link
Copy Markdown
Member Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c0d0a64a9c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +135 to +137
const state = context.readme.find((s) => s.path === path)
const seed = state?.state === 'present-declared' || state?.state === 'present-undeclared' ? state.content : ''
onRequestEditor?.({ kind: 'readme', path, option, content: seed })

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Seed newly created README content from facet identity

When both README paths are absent and the author selects Create, this branch supplies '' to the external editor instead of the identity-derived template. As a result, accepting the editor unchanged creates and declares an empty README, despite readmeSeedContent specifically defining the template for absent states and the intended create flow seeding README content from the facet name and description. Use readmeSeedContent(state, form.fields.name.value, form.fields.description.value) here as well, while retaining existing bytes for present files.

Useful? React with 👍 / 👎.

Comment thread packages/cli/src/tui/views/edit/wizard.tsx
Comment thread packages/cli/src/tui/views/edit/wizard.tsx
@greptile-apps

greptile-apps Bot commented Jul 24, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds independent README action tracking for README.md and README in the edit wizard: a new ReadmeAction discriminated union, a dedicated readme wizard phase (ReadmePanelView), session wiring via readmeActions: Map<ReadmePath, ReadmeAction>, and tagged EditEditorRequest for editor round-trips. The adoption guarantee that on-disk bytes are never written is structural (the adopt variant carries no content).

  • Engine layer: readme-actions.ts defines the full state machine — readmeActionOptions gates legal options per state, applyReadmeDeclaration handles manifest-only deltas, and readmeFileOperations emits write/delete operations. Broad unit coverage confirms all variants and the structural byte-preservation for adopt.
  • Wizard layer: handleReadmeResolve seeds non-editor actions (including scaffold) from the form's current name/description at README-phase time; since the README phase precedes the editing phase, name/description changes made during editing produce a scaffold README that doesn't match the final manifest identity.
  • Round-trip and tests: Editor cancellation queues nothing; the dual-path independence session tests, transactional rollback test, and e2e create tests are all well-scoped.

Confidence Score: 5/5

Safe to merge; the adoption byte-preservation guarantee is structural and well-tested, editor cancellation correctly queues nothing, and the round-trip wiring is correct.

The only finding is the scaffold action capturing template bytes at README-phase time, before the user can edit the facet name in the subsequent editing step — a mismatch that only arises in the uncommon declared-missing state when name or description is also changed in the same session. Everything else — the discriminated union design, declaration vs. file-op separation, snapshot threading, and transactional rollback — holds up under scrutiny and is backed by thorough tests.

packages/cli/src/tui/views/edit/wizard.tsx — specifically handleReadmeResolve where the scaffold template seed is captured from form values that may be updated later in the editing phase.

Reviews (4): Last reviewed commit: "TODO" | Re-trigger Greptile

Comment on lines +133 to +139
const handleReadmeEdit = useCallback(
(path: ReadmePath, option: ReadmeActionOption) => {
const state = context.readme.find((s) => s.path === path)
const seed = state?.state === 'present-declared' || state?.state === 'present-undeclared' ? state.content : ''
onRequestEditor?.({ kind: 'readme', path, option, content: seed })
},
[context.readme, onRequestEditor],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Editor seeded with empty string for create

handleReadmeEdit computes the seed content with a manual state check that returns '' for anything other than present-declared or present-undeclared. The create option is only offered for absent-undeclared state, so it falls into the else branch and opens the external editor with an empty buffer. readmeSeedContent is already imported and handles absent-undeclared by returning readmeTemplate(name, description) — the same template the PR description says create should be seeded from. The fix is to call readmeSeedContent(state, form.fields.name.value, form.fields.description.value) here (matching handleReadmeResolve), and add form.fields.name.value and form.fields.description.value to the useCallback dependency array.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a738ae8. Configure here.

Comment thread packages/cli/src/tui/views/edit/readme-panel-view.tsx

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a738ae81c3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +53 to +56
const options = useMemo(() => readmeActionOptions(state), [state])

const selectedKind = action ? readmeOptionKindFor(action) : null
const selectedIndex = selectedKind ? options.findIndex((o) => o.kind === selectedKind) : -1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Let authors clear a queued README action

After an author selects Adopt, Create, Edit, Remove, or another README action, this row offers only the non-none options and onSelect can never clear the stored action. Thus an author who changes their mind while continuing to edit other fields cannot restore “leave as-is”; the prior README mutation remains queued and will be applied. Add an explicit leave/clear path that removes or replaces the action with none.

Useful? React with 👍 / 👎.

@eXamadeus
eXamadeus force-pushed the julian/07-23-extend_edit_reconciliation_to_structured_item_identities_supplementary_file_scanning_transactional_apply_and_exact-path_confirmation_preview branch from 28c186f to a27000a Compare July 24, 2026 04:03
@eXamadeus
eXamadeus force-pushed the julian/07-23-add_independent_tagged_readme_actions_panel_view_and_editor_round-trip_integration_for_both_conventional_paths branch from a738ae8 to d2de027 Compare July 24, 2026 04:03

eXamadeus commented Jul 24, 2026

Copy link
Copy Markdown
Member Author

Merge activity

  • Jul 24, 4:47 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jul 24, 4:59 AM UTC: Graphite rebased this pull request as part of a merge.
  • Jul 24, 4:59 AM UTC: @eXamadeus merged this pull request with Graphite.

@eXamadeus
eXamadeus changed the base branch from julian/07-23-extend_edit_reconciliation_to_structured_item_identities_supplementary_file_scanning_transactional_apply_and_exact-path_confirmation_preview to graphite-base/459 July 24, 2026 04:56
@eXamadeus
eXamadeus changed the base branch from graphite-base/459 to main July 24, 2026 04:57
@eXamadeus
eXamadeus force-pushed the julian/07-23-add_independent_tagged_readme_actions_panel_view_and_editor_round-trip_integration_for_both_conventional_paths branch from d2de027 to 9ba621d Compare July 24, 2026 04:58
@eXamadeus
eXamadeus merged commit 896fc1d into main Jul 24, 2026
7 checks passed
@eXamadeus
eXamadeus deleted the julian/07-23-add_independent_tagged_readme_actions_panel_view_and_editor_round-trip_integration_for_both_conventional_paths branch July 24, 2026 04:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant